home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Workspace / Locus / Source / GroupBrowser.m < prev    next >
Text File  |  1995-06-12  |  10KB  |  545 lines

  1.  
  2. /*
  3.     Copyright 1993  Jeremy Slade.
  4.  
  5.     You are free to use all or any parts of the Locus project
  6.     however you wish, just give credit where credit is due.
  7.     The author (Jeremy Slade) shall not be held responsible
  8.     for any damages that result out of use or misuse of any
  9.     part of this project.
  10.  
  11. */
  12.  
  13. /*
  14.  
  15.     Project: Locus
  16.     
  17.     Class: GroupBrowser
  18.     
  19.     Description: See GroupBrowser.h
  20.  
  21.     Original Author: Jeremy Slade
  22.     
  23.     Revision History:
  24.         Created
  25.             V.101    JSG Wed Feb  3 23:53:15 GMT-0700 1993
  26.             
  27. */
  28.  
  29.  
  30. #import "GroupBrowser.h"
  31.  
  32. #import "FolderController.h"
  33. #import "Globals.h"
  34. #import "GroupBrowserMatrix.h"
  35. #import "ItemCell.h"
  36.  
  37. #import <objc/List.h>
  38. #import <string.h>
  39.  
  40.  
  41. @interface GroupBrowser ( Private )
  42. - _tellDelegateSelChanged;
  43. @end
  44.  
  45.  
  46. @implementation GroupBrowser
  47.  
  48.  
  49. // -------------------------------------------------------------------------
  50. //   Creating, initializing methods
  51. // -------------------------------------------------------------------------
  52.  
  53.  
  54. + initialize
  55. {
  56.     [self setVersion:GroupBrowser_VERSION];
  57.     return ( self );
  58. }
  59.  
  60.  
  61.  
  62. - initFrame:(const NXRect *)frameRect
  63. {
  64.     NXRect rect;
  65.  
  66.     [super initFrame:frameRect];
  67.     
  68.     NXSetRect ( &rect, 0, 0, 0, 0 );
  69.     [ScrollView getContentSize:&rect.size forFrameSize:&frameRect->size
  70.         horizScroller:NO vertScroller:YES borderType:NX_BEZEL];
  71.         
  72.     matrix = [[GroupBrowserMatrix alloc] initFrame:&rect
  73.         mode:NX_LISTMODE
  74.         cellClass:[ItemCell class]
  75.         numRows:0
  76.         numCols:1];
  77.     rect.size.height = rect.size.width = 1.0;
  78.     [matrix setIntercell:&rect.size];
  79.     [matrix setAutoscroll:YES];
  80.     [[[matrix setTarget:self]
  81.         setAction:@selector(doAction:)]
  82.         setDoubleAction:@selector(doDoubleAction:)];
  83.  
  84.     [self allowMultiSel:YES];
  85.     [[self setDocView:matrix] free];
  86.     [self setBorderType:NX_BEZEL];
  87.     [[self setDynamicScrolling:YES] setDisplayOnScroll:YES];
  88.     [self setVertScrollerRequired:YES];
  89.     
  90.     [self setAutoresizeSubviews:YES];
  91.     
  92.     [self registerForDraggedTypes:dragInTypes count:DRAGINTYPES];
  93.  
  94.     lastTime = 0;
  95.     return ( self );
  96. }
  97.  
  98.  
  99.  
  100. - free
  101. {
  102.     return ( [super free] );
  103. }
  104.  
  105.  
  106.  
  107. // -------------------------------------------------------------------------
  108. //   Setting the Group to be displayed
  109. // -------------------------------------------------------------------------
  110.  
  111.  
  112. - showGroup:group
  113. {
  114.     id oldList;
  115.  
  116. //if ( DEBUGGING ) printf ( "GroupBrowser: loading browser...\n" );
  117.  
  118.     oldList = [matrix setGroup:group];
  119.     if ( ![oldList isKindOf:[Group class]] ) [oldList free];
  120.  
  121.     // Set the group to be our target
  122.     [self setTarget:group];
  123.     
  124.     [self display];
  125. //if ( DEBUGGING ) printf ( "    Done.\n" );
  126.     return ( self );
  127. }
  128.  
  129.  
  130.  
  131. // -------------------------------------------------------------------------
  132. //   Drawing
  133. // -------------------------------------------------------------------------
  134.  
  135.  
  136. - resizeSubviews:(const NXSize *)oldSize
  137. /*
  138.     Retile the browser
  139. */
  140. {
  141.     NXRect rect;
  142.     NXSize size;
  143.     
  144.     [super resizeSubviews:oldSize];
  145.     
  146.     [self getDocVisibleRect:&rect];
  147.     [matrix getCellSize:&size];
  148.     size.width = rect.size.width;
  149.     [[matrix setCellSize:&size] sizeToCells];
  150.     
  151.     [matrix getFrame:&rect];
  152.     [self getContentSize:&size];
  153.     if ( rect.size.height < size.height ) {
  154.         rect.size.height = size.height;
  155.         [matrix setFrame:&rect];
  156.     }
  157.     
  158.     return ( self );
  159. }
  160.  
  161.  
  162.  
  163. // -------------------------------------------------------------------------
  164. //   Setting the delegate
  165. // -------------------------------------------------------------------------
  166.  
  167.  
  168. - setDelegate:anObject
  169. {
  170.     id old = delegate;
  171.     delegate = anObject;
  172.     return ( old );
  173. }
  174.  
  175.  
  176.  
  177. - delegate
  178. {
  179.     return ( delegate );
  180. }
  181.  
  182.  
  183.  
  184. // -------------------------------------------------------------------------
  185. //   Setting behavior
  186. // -------------------------------------------------------------------------
  187.  
  188.  
  189. - (BOOL)acceptsFirstMouse
  190. {
  191.     return ( YES );
  192. }
  193.  
  194.  
  195.  
  196. - allowMultiSel:(BOOL)flag
  197. {
  198.     allowMultiSel = flag;
  199.     if ( allowMultiSel == YES ) [matrix setMode:NX_LISTMODE];
  200.         else [matrix setMode:NX_RADIOMODE];
  201.     return ( self );
  202. }
  203.  
  204.  
  205.  
  206. - (BOOL)doesAllowMultiSel
  207. {
  208.     return ( allowMultiSel );
  209. }
  210.  
  211.  
  212.  
  213. - setEnabled:(BOOL)flag
  214. {
  215.     [matrix setEnabled:flag];
  216.     return ( self );
  217. }
  218.  
  219.  
  220.  
  221. - (BOOL)isEnabled
  222. {
  223.     return ( [matrix isEnabled] );
  224. }
  225.  
  226.  
  227.  
  228. // -------------------------------------------------------------------------
  229. //   Setting target and action
  230. // -------------------------------------------------------------------------
  231.  
  232.  
  233. - setTarget:anObject
  234. {
  235.     target = anObject;
  236.     return ( self );
  237. }
  238.  
  239.  
  240.  
  241. - setAction:(SEL)selector
  242. {
  243.     action = selector;
  244.     return ( self );
  245. }
  246.  
  247.  
  248.  
  249. - setDoubleAction:(SEL)selector
  250. {
  251.     doubleAction = selector;
  252.     return ( self );
  253. }
  254.  
  255.  
  256.  
  257. - target
  258. {
  259.     return ( target );
  260. }
  261.  
  262.  
  263.  
  264. - (SEL)action
  265. {
  266.     return ( action );
  267. }
  268.  
  269.  
  270.  
  271. - (SEL)doubleAction
  272. {
  273.     return ( doubleAction );
  274. }
  275.  
  276.  
  277.  
  278. - doAction:sender
  279. {
  280.     [matrix determineSelectionCount];
  281.     return ( [target perform:action with:self] );
  282. }
  283.  
  284.  
  285.  
  286. - doDoubleAction:sender
  287. {
  288.     [matrix determineSelectionCount];
  289.     return ( [target perform:doubleAction with:self] );
  290. }
  291.  
  292.  
  293.  
  294. // -------------------------------------------------------------------------
  295. //   Making selections
  296. // -------------------------------------------------------------------------
  297.  
  298.  
  299. - selectAll:sender
  300. {
  301.     [matrix selectAll:self];
  302.     return ( self );
  303. }
  304.  
  305.  
  306. - selectUp:sender
  307. /*
  308.     Move the selection up one item, or start at the bottom if nothing (or more than 1) is already selected.
  309. */
  310. {
  311.     int row, col;
  312.     if ( [matrix selectionCount] ) {
  313.         [matrix getRow:&row andCol:&col ofCell:[matrix selectedCell]];
  314.         if ( row ) row--;
  315.         [self selectRow:row];
  316.     } else
  317.         [self selectRow:[[matrix cellList] count]-1]; // Select last cell
  318.     return ( self );
  319. }
  320.  
  321.  
  322. - selectDown:sender
  323. /*
  324.     Move the selection down one item, or start at the top if nothing (or more than 1) is already selected.
  325. */
  326. {
  327.     int row, col;
  328.     if ( [matrix selectionCount] ) {
  329.         [matrix getRow:&row andCol:&col ofCell:[matrix selectedCell]];
  330.         if ( row < [matrix cellCount] ) row++;
  331.         [self selectRow:row];
  332.     } else
  333.         [self selectRow:0]; // Select first cell
  334.     return ( self );
  335. }
  336.  
  337.  
  338. - selectedCell
  339. {
  340.     return ( [matrix selectedCell] );
  341. }
  342.  
  343.  
  344. - selection
  345. /*
  346.     This method returns the currently selected item in the matrix if there is only one selected, other wise it creates a ItemList object, fills it with the selected items, and returns it.  The caller does not need to free the returned List because it is kept as a static internal to this method.
  347. */
  348. {
  349.     return ( [matrix selection] );
  350. }
  351.  
  352.  
  353. - selectionList
  354. /*
  355.     This method is like the -selection method, but it always returns an ItemList object., that must be freed by the caller
  356. */
  357. {
  358.     return ( [matrix selectionList] );
  359. }
  360.  
  361.  
  362. - (int)selectionCount
  363. /*
  364.     Returns the number of items curerntly selected
  365. */
  366. {
  367.     return ( [matrix selectionCount] );
  368. }
  369.  
  370.  
  371. const char *upStr ( const char *str )
  372. /* Convert str to uppercase */
  373. {
  374.     static char s[MAXPATHLEN+1];
  375.     const char *src;
  376.     char *dest;
  377.     
  378.     src = str;
  379.     dest = s;
  380.     do {
  381.         *dest++ = NXToUpper ( *src++ );
  382.     } while ( *src );
  383.     *dest = '\0';
  384.     return ( s );
  385. }
  386.  
  387.  
  388. #define KEY_TRAP_INTERVAL    120
  389. - selectKey:(unsigned int)charCode time:(long)time
  390. /*
  391.     Searches the cells by filename, looking for the first cell beginning with/ the selected key.  Search is not case sensitive.  If a cell is found, it is selected.
  392. */
  393. {
  394.     int count, row;
  395.     id list = [matrix cellList];
  396.     id cell;
  397.     const char *filename;
  398.     char match[21];
  399.     
  400.     /*
  401.         Determime if selectFile needs to be reset
  402.     */
  403.     if ( time-lastTime > KEY_TRAP_INTERVAL ) {
  404.         selectKey = 0;
  405.         strcpy ( selectFile, "" );
  406.     } 
  407.         
  408.     lastTime = time;
  409.  
  410.     // Convert charCode to upper case for case-insensitive matching
  411.     charCode = NXToUpper ( charCode );
  412.     
  413.     // First search selected cell for match
  414.     if (  selectKey  ) {
  415.         filename = upStr ( [[matrix selectedCell] filename] );
  416.         if ( charCode == selectFile[selectKey] ) {
  417.             selectKey++;
  418.             return ( self );
  419.         }
  420.     }
  421.     
  422.     // Search [matrix cellList] for matching cell
  423.     row = selectKey ? [matrix selectedRow] : 0;
  424.     for ( count=[list count]; row<count; row++ ) {
  425.         cell = [list objectAt:row];
  426.         filename = upStr ( [cell filename] );
  427.         sprintf ( match, "%.*s%c", selectKey, selectFile, (char)charCode );
  428.         if ( selectKey && !strncmp ( match, filename, selectKey+1 ) ) {
  429.  
  430.             // Found a match
  431.             [matrix selectCell:cell];
  432.             [matrix scrollCellToVisible:row :0];
  433.             selectKey++;
  434.             strcpy ( selectFile, filename );
  435.             
  436.             [self _tellDelegateSelChanged];
  437.             return ( self );
  438.         }
  439.         if ( charCode == filename[0] ) {
  440.             
  441.             // Found a match
  442.             [matrix selectCell:cell];
  443.             [matrix scrollCellToVisible:row :0];
  444.             selectKey = 1;
  445.             strncpy ( selectFile, filename, 10 );
  446.                 
  447.             [self _tellDelegateSelChanged];
  448.             return ( self );
  449.         }
  450.     }
  451.         
  452.     // No match was found
  453.     NXBeep ();
  454.     return ( self );
  455. }                
  456.  
  457.  
  458. - selectRow:(unsigned int)row
  459. {
  460.     [matrix selectCellAt:row :0];
  461.     [matrix scrollCellToVisible:row :0];
  462.     [self _tellDelegateSelChanged];
  463.     return ( self );
  464. }
  465.  
  466.  
  467. - scrollRowToVisible:(unsigned int)row
  468. {
  469.     [matrix scrollCellToVisible:row :0];
  470.     return ( self );
  471. }
  472.  
  473.  
  474. - scrollToSelection
  475. {
  476.     [matrix scrollCellToVisible:[matrix selectedRow] :0];
  477.     return ( self );
  478. }
  479.  
  480.  
  481.  
  482. // -------------------------------------------------------------------------
  483. //   NXDraggingDestination Protocol - forward to FolderController
  484. // -------------------------------------------------------------------------
  485.  
  486.  
  487. - (NXDragOperation)draggingEntered:(id <NXDraggingInfo>)sender
  488. {
  489.     [folderController setDragDest:self];
  490.     return ( [folderController draggingEntered:sender] );
  491. }
  492.  
  493.  
  494.  
  495. - (NXDragOperation)draggingUpdated:(id <NXDraggingInfo>)sender
  496. {
  497.     return ( [folderController draggingUpdated:sender] );
  498. }
  499.  
  500.  
  501.  
  502. - draggingExited:(id <NXDraggingInfo>)sender
  503. {
  504.     return ( [folderController draggingExited:sender] );
  505. }
  506.  
  507.  
  508.  
  509. - (BOOL)prepareForDragOperation:(id <NXDraggingInfo>)sender
  510. {
  511.     return ( [folderController prepareForDragOperation:sender] );
  512. }
  513.  
  514.  
  515.  
  516. - (BOOL)performDragOperation:(id <NXDraggingInfo>)sender
  517. {
  518.     return ( [folderController performDragOperation:sender] );
  519. }
  520.  
  521.  
  522.  
  523. - concludeDragOperation:(id <NXDraggingInfo>)sender
  524. {
  525.     return ( [folderController concludeDragOperation:sender] );
  526. }
  527.  
  528.  
  529. @end
  530.  
  531.  
  532. @implementation GroupBrowser ( Private )
  533.  
  534. - _tellDelegateSelChanged
  535. {
  536.     if ( [delegate respondsTo:@selector(browserSelectionChanged:)] )
  537.         [delegate browserSelectionChanged:self];
  538.     return ( self );
  539. }
  540.  
  541.  
  542. @end
  543.  
  544.  
  545.